#import "ScreenTransition.h"
#import <MAUtil/Graphics.h>
#import "std.h"

MAUI::Screen* ScreenTransition::gScreen = NULL;
ScreenTransition* ScreenTransition::gWidget = NULL;
TransitionType ScreenTransition::currentType = SIDEBYSIDE;

void ScreenTransition::makeTransition(MAUI::Screen* fromScreen,
		MAUI::Screen* toScreen, int direction, int duration,
		TransitionType type) {
	if (gScreen != 0) {
		return;
	}
	gScreen = new MAUI::Screen();
	gWidget = new ScreenTransition();
	gScreen->setMain(gWidget);
	gWidget->fromMainWidget = fromScreen->getMain();
	gWidget->toScreen = toScreen;
	gWidget->toMainWidget = toScreen->getMain();
	gWidget->direction = direction;
	gWidget->duration = duration;
	gWidget->start_time = maGetMilliSecondCount();
	gWidget->updateAlpha(gWidget->start_time);
	currentType = type;

	// This will tell the widget to fix stuff before being drawn
	gWidget->toMainWidget->update();

	gScreen->show();
	MAUtil::Environment::getEnvironment().addTimer(gWidget, 20, -1);
}

void ScreenTransition::drawWidget() {
	if (currentType == REVEALFROMBELOW) {
		toMainWidget->setEnabled(true);
		toMainWidget->draw();
		toMainWidget->setEnabled(false);

		Gfx_translate((int) (-direction * alpha * scrW), 0);
		fromMainWidget->setEnabled(true);
		fromMainWidget->draw();
		fromMainWidget->setEnabled(false);
	} else if (currentType == MOVEOVERTOP) {
		fromMainWidget->setEnabled(true);
		fromMainWidget->draw();
		fromMainWidget->setEnabled(false);

		Gfx_translate((int) (-direction * alpha * scrW) + scrW, 0);
		toMainWidget->setEnabled(true);
		toMainWidget->draw();
		toMainWidget->setEnabled(false);
	} else {
		Gfx_translate((int) (-direction * alpha * scrW), 0);
		fromMainWidget->setEnabled(true);
		fromMainWidget->draw();
		fromMainWidget->setEnabled(false);

		Gfx_translate(direction * scrW, 0);
		toMainWidget->setEnabled(true);
		toMainWidget->draw();
		toMainWidget->setEnabled(false);
	}
}

double ScreenTransition::square_sigmoid(double t) {
	if (t < 0.0) {
		return 0.0;
	} else if (t < 0.5) {
		return 2 * t * t;
	} else if (t < 1.0) {
		float tm1 = (t - 1.0);
		return 1.0 - 2 * tm1 * tm1;
	} else {
		return 1.0;
	}
}

void ScreenTransition::updateAlpha(int now) {
	alpha = double(now - this->start_time) / double(duration);
	alpha = square_sigmoid(alpha);
}

void ScreenTransition::runTimerEvent() {
	updateAlpha(maGetMilliSecondCount());
	if (alpha >= 1.0) {
		MAUtil::Environment::getEnvironment().removeTimer(this);
		this->toScreen->show();
		delete gScreen;
		gScreen = 0;
		delete gWidget; // I.e. this
		gWidget = 0;
	} else {
		this->requestRepaint();
	}
}
